﻿using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FySystem.Logs
{
    internal class LogFlow
    {
        private ManualResetEventSlim _allDone = new ManualResetEventSlim(false);
        private ILog _ilog = null;
        private ArrayPool<LogItem> _logPool = ArrayPool<LogItem>.Shared;
        /// <summary>
        /// 日志队列
        /// </summary>
        private ConcurrentQueue<LogItem> _logQueue = new ConcurrentQueue<LogItem>();

        /// <summary>
        /// 将日志加入日志队列
        /// </summary>
        /// <param name="log"></param>
        internal void Enqueue(LogItem log)
        {
            try
            {
                _logQueue.Enqueue(log);
                _allDone.Set();
            }
            catch { }
        }

        internal LogFlow(ILog log)
        {
            _ilog = log;
            Task task = new Task(Start);
            task.Start();
        }

        /// <summary>
        /// 开始日志写入线程
        /// </summary>
        private void Start()
        {
            LogItem[] logs = null;
            int num = 0;

            while (true)
            {
                try
                {
                    _allDone.Reset();

                    num = _logQueue.Count;
                    if (num <= 0)
                    {
                        _allDone.Wait();
                        continue;
                    }

                    logs = _logPool.Rent(num);
                    for(int i = 0; i < num; i++)
                    {
                        _logQueue.TryDequeue(out logs[i]);
                    }

                    //这里不能写异步函数，因为用了数组池
                    _ilog.WriteLog(logs.AsSpan(0, num));
                    _logPool.Return(logs);
                }
                catch { }
            }
        }
    }
}
